#pragma once

#include <map>
#include <algorithm>
#include <memory>
#include "QuoteSocket.h"


class CBroadcaster;
class CPeerSocket;

class CQuoteBroadcast
{
public:
	CQuoteBroadcast( HWND hWnd, UINT uMsg );
	~CQuoteBroadcast(void);

public:
	bool OpenPort( LPCTSTR strPort );
	bool Broadcast( BYTE* pBuffer, int nLen );

private:
	void Quitthread( void );

private:
	CWinThread* m_pThread;
};
typedef auto_ptr<CQuoteBroadcast> AP_QUOTEBCAST;

class CCodec;
class CBroadcaster
	: public CQuoteSocket
{
public:
	CBroadcaster( UINT nID );
	~CBroadcaster( void );
	bool Listen( void )
	{
		if( !CQuoteSocket::Listen( SOMAXCONN ) ) 
		{
			PostFailedSockMsg( ISockMsg::SA_LISTEN );
			return false;
		}
		PostStateSockMsg( ISockMsg::SS_LISTENING );
		return true;
	}

	bool Broadcast( BYTE* pBuffer, int nLen );
	bool Broadcast( const Package& pack );

// public:
// 	bool PushBack( Package* pPack );
// 	Package* PopFront( void );

	void DeletePeer( CPeerSocket* peer );

protected:
	virtual void OnClose( int nErrorCode );
	virtual void OnAccept( int nErrorCode );
	virtual void OnSend( int nErrorCode );

	int MakePeerID( void ) const;

private:
	typedef std::map< UINT, CPeerSocket* >  MAP_PEER;
	MAP_PEER	m_mapSockets;

	void ClearMap( void );
	static void RemovePeer( MAP_PEER::value_type& peer );

	typedef std::auto_ptr<CCodec> AP_CODEC;
	AP_CODEC	m_apCodec;

	int			m_nPackCount;

// private:
// 	std::deque< Package* > QUE_PACK;
// 	QUE_PACK	m_quePacks;
};

inline void CBroadcaster::ClearMap( void )
{
	std::for_each( m_mapSockets.begin(), 
		m_mapSockets.end(), 
		RemovePeer );

	m_mapSockets.clear();
}

inline int CBroadcaster::MakePeerID( void ) const
{
	static UINT ID = 1;
	return ID++;
}
